package com.moxiao.yfjh.module.activity.controller.admin.activityInfo;

import com.moxiao.yfjh.framework.common.pojo.CommonResult;
import com.moxiao.yfjh.framework.common.pojo.PageResult;
import com.moxiao.yfjh.framework.excel.core.util.ExcelUtils;
import com.moxiao.yfjh.framework.operatelog.core.annotations.OperateLog;
import com.moxiao.yfjh.module.activity.common.ActivityNotifyMessageUtils;
import com.moxiao.yfjh.module.activity.common.GenActiveNoCommonUtil;
import com.moxiao.yfjh.module.activity.controller.admin.activityInfo.vo.*;
import com.moxiao.yfjh.module.activity.controller.admin.activityPackage.vo.ActivityPackageCreateReqVO;
import com.moxiao.yfjh.module.activity.controller.admin.activityPackage.vo.ActivityPackageExportReqVO;
import com.moxiao.yfjh.module.activity.controller.admin.activityPackage.vo.ActivityPackageRespVO;
import com.moxiao.yfjh.module.activity.convert.activityEnroll.ActivityEnrollConvert;
import com.moxiao.yfjh.module.activity.convert.activityInfo.ActivityInfoConvert;
import com.moxiao.yfjh.module.activity.convert.activityPackage.ActivityPackageConvert;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityEnroll.ActivityEnrollDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityInfo.ActivityInfoDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityPackage.ActivityPackageDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.merchantInfo.MerchantInfoDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.productInfo.ProductInfoDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.productType.ProductTypeDO;
import com.moxiao.yfjh.module.activity.service.activityEnroll.ActivityEnrollService;
import com.moxiao.yfjh.module.activity.service.activityInfo.ActivityInfoService;
import com.moxiao.yfjh.module.activity.service.activityPackage.ActivityPackageService;
import com.moxiao.yfjh.module.activity.service.merchantInfo.MerchantInfoService;
import com.moxiao.yfjh.module.activity.service.productInfo.ProductInfoService;
import com.moxiao.yfjh.module.activity.service.productType.ProductTypeService;
import com.moxiao.yfjh.module.blind.dal.dataobject.member.BlindMemberUserDO;
import com.moxiao.yfjh.module.blind.service.member.BlindMemberUserService;
import com.moxiao.yfjh.module.system.dal.dataobject.user.AdminUserDO;
import com.moxiao.yfjh.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.moxiao.yfjh.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.moxiao.yfjh.framework.common.pojo.CommonResult.error;
import static com.moxiao.yfjh.framework.common.pojo.CommonResult.success;
import static com.moxiao.yfjh.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static com.moxiao.yfjh.framework.operatelog.core.enums.OperateTypeEnum.UPDATE;
import static com.moxiao.yfjh.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static com.moxiao.yfjh.module.activity.enums.ErrorCodeConstants.ACTIVITY_ENROLL_PAY_REFUND_NOT_EXISTS;
import static com.moxiao.yfjh.module.activity.enums.ErrorCodeConstants.ENROLL_NO_RELATED_ACTIVITIES_FOUND_NOT_EXISTS;

@Tag(name = "管理后台 - 相亲活动信息")
@RestController
@RequestMapping("/activity/info")
@Validated
@Slf4j
public class ActivityInfoController {

    @Resource
    private ActivityInfoService infoService;
    @Resource
    private ActivityPackageService packageService;
    @Resource
    private MerchantInfoService merchantInfoService;
    @Resource
    private ProductInfoService productInfoService;
    @Resource
    private GenActiveNoCommonUtil genActiveNoCommonUtil;
    @Resource
    private ActivityPackageService activityPackageService;
    @Resource
    private ActivityEnrollService enrollService;
    @Resource
    private BlindMemberUserService userService;
    @Resource
    private ProductTypeService productTypeService;
    @Resource
    private ActivityNotifyMessageUtils messageUtils;
    @Resource
    private AdminUserService adminUserService;
    /**
     * 延迟队列名称
     */
    private String delayQueueName = "delayQueue";

    public static <T> String parseListToStr(List<T> list) {
        String result = list.stream().map(String::valueOf).collect(Collectors.joining(","));
        return result;
    }

    @PutMapping("/update")
    @Operation(summary = "更新相亲活动信息")
    @PreAuthorize("@ss.hasPermission('activity:info:update')")
    public CommonResult<Boolean> updateInfo(@Valid @RequestBody ActivityInfoUpdateReqVO updateReqVO) {
        infoService.updateInfo(updateReqVO);
        // 验证活动商品是否存在，不存在则是新增，存在则是修改
        activityPackageService.updatePackage(updateReqVO.getReqVO());
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除相亲活动信息")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('activity:info:delete')")
    public CommonResult<Boolean> deleteInfo(@RequestParam("id") Long id) {
        ActivityInfoDO info = infoService.getInfo(id);
        if (Objects.nonNull(info)) {
            if (Objects.equals(info.getStatus(), 4)) {
                return error(500, "该活动已开始，不能删除！");
            }
        }
        infoService.deleteInfo(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得相亲活动信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('activity:info:query')")
    public CommonResult<ActivityInfoRespVO> getInfo(@RequestParam("id") Long id) {
        ActivityInfoDO info = infoService.getInfo(id);
        ActivityInfoRespVO activityInfoRespVO = ActivityInfoConvert.INSTANCE.convert(info);
        if (Objects.nonNull(activityInfoRespVO)) {
            ActivityPackageExportReqVO activityPackageReqVO = new ActivityPackageExportReqVO();
            activityPackageReqVO.setActiveId(id);
            List<ActivityPackageDO> packageList = packageService.getPackageList(activityPackageReqVO);
            if (CollectionUtils.isNotEmpty(packageList)) {
                List<ActivityPackageRespVO> activityPackageRespVOS = ActivityPackageConvert.INSTANCE.convertList(packageList);
                activityPackageRespVOS.forEach(packageProductRespVO -> {
                    Long merchantId = packageProductRespVO.getMerchantId();
                    MerchantInfoDO merchantInfo = merchantInfoService.getMerchantInfo(merchantId);
                    if (Objects.nonNull(merchantInfo)) {
                        packageProductRespVO.setMerchantName(merchantInfo.getName());
                        packageProductRespVO.setAddress(merchantInfo.getAddress());
                    }
                    // 商品相关信息
                    ProductInfoDO productInfoDO = productInfoService.getProductInfo(packageProductRespVO.getProductId());
                    if (Objects.nonNull(merchantInfo)) {
                        packageProductRespVO.setProductName(productInfoDO.getName());
                        packageProductRespVO.setSupplyPrice(productInfoDO.getSupplyPrice());
                        packageProductRespVO.setPlatformPrice(productInfoDO.getPlatformPrice());
                        packageProductRespVO.setProductIntroduct(productInfoDO.getProductIntroduct());
                        // 商品类型
                        ProductTypeDO productType = productTypeService.getProductType(productInfoDO.getProductType());
                        if (Objects.nonNull(productType)) {
                            packageProductRespVO.setProductTypeName(productType.getName());
                        }
                    }
                });
                activityInfoRespVO.setPackageProductRespVOList(activityPackageRespVOS);
            }
        }
        //TODO 获得已报名活动人员的数量
        // 男人
        int registeredMenNum = enrollService.getNumber(info.getId(), (byte) 1, null);
        activityInfoRespVO.setRegisteredMenNum(registeredMenNum);
        // 女人
        int registeredWomenNum = enrollService.getNumber(info.getId(), (byte) 2, null);
        activityInfoRespVO.setRegisteredWomenNum(registeredWomenNum);
        // 计算应收金额
        if (StringUtils.isNotBlank(activityInfoRespVO.getMenNum()) && StringUtils.isNotBlank(activityInfoRespVO.getWomenNum())) {
            Integer num = Integer.parseInt(activityInfoRespVO.getMenNum()) + Integer.parseInt(activityInfoRespVO.getWomenNum());
            BigDecimal decimal = new BigDecimal(activityInfoRespVO.getActiveCost());
            activityInfoRespVO.setReceivableAmount(decimal.multiply(BigDecimal.valueOf(num)));
            // 成本价
            BigDecimal cost = infoService.getSupplypriceAmount(activityInfoRespVO.getId());
            activityInfoRespVO.setCostTotal(cost.multiply(BigDecimal.valueOf(num)));
        }
        // 实收
        activityInfoRespVO.setActualAmount(enrollService.getActivityIdAmount(info.getId()));
        BlindMemberUserDO userDO = userService.getMemberUser(activityInfoRespVO.getHeadUserId());
        if (Objects.nonNull(userDO)) {
            activityInfoRespVO.setHead(userDO.getNickname());
            activityInfoRespVO.setHeadSex(userDO.getSex());
        }
        if (StringUtils.isNotBlank(activityInfoRespVO.getAuditUser())) {
            AdminUserDO adminUserDO = adminUserService.getUser(Long.valueOf(activityInfoRespVO.getAuditUser()));
            if (Objects.nonNull(adminUserDO)) {
                activityInfoRespVO.setAuditUser(adminUserDO.getNickname());
            }
        }

        return success(activityInfoRespVO);

    }

    @GetMapping("/list")
    @Operation(summary = "获得相亲活动信息列表")
    @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
    @PreAuthorize("@ss.hasPermission('activity:info:query')")
    public CommonResult<List<ActivityInfoRespVO>> getInfoList(@RequestParam("ids") Collection<Long> ids) {
        List<ActivityInfoDO> list = infoService.getInfoList(ids);
        return success(ActivityInfoConvert.INSTANCE.convertList(list));
    }

    @GetMapping("/page")
    @Operation(summary = "获得相亲活动信息分页")
    @PreAuthorize("@ss.hasPermission('activity:info:query')")
    public CommonResult<PageResult<ActivityInfoRespVO>> getInfoPage(@Valid ActivityInfoPageReqVO pageVO) {
        PageResult<ActivityInfoDO> pageResult = infoService.getInfoPage(pageVO);
        return success(ActivityInfoConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出相亲活动信息 Excel")
    @PreAuthorize("@ss.hasPermission('activity:info:export')")
    @OperateLog(type = EXPORT)
    public void exportInfoExcel(@Valid ActivityInfoExportReqVO exportReqVO,
                                HttpServletResponse response) throws IOException {
        List<ActivityInfoDO> list = infoService.getInfoList(exportReqVO);
        // 导出 Excel
        List<ActivityInfoExcelVO> datas = ActivityInfoConvert.INSTANCE.convertList02(list);
        ExcelUtils.write(response, "相亲活动信息.xls", "数据", ActivityInfoExcelVO.class, datas);
    }

    @PostMapping("/auditActivity")
    @Operation(summary = "活动审核")
    @Parameters({
            @Parameter(name = "id", description = "活动id", required = true, example = "1"),
            @Parameter(name = "auditStatus", description = "状态", required = true, example = "1"),
            @Parameter(name = "rejectReason", description = "审核原因", required = true, example = "1024")
    })
    @OperateLog(type = UPDATE)
    @PreAuthorize("@ss.hasPermission('activity:info:audit')")
    public CommonResult<Boolean> auditActivity(@RequestBody ActivityInfoUpdateReqVO updateReqVO) {
        ActivityInfoDO activityInfo = infoService.getInfo(updateReqVO.getId());
        if (updateReqVO.getAuditStatus() == 1) {
            updateReqVO.setStatus((byte) 2);
            updateReqVO.setId(updateReqVO.getId());
            updateReqVO.setAuditUser(String.valueOf(getLoginUserId()));
            updateReqVO.setAuditStatus(updateReqVO.getAuditStatus());
            updateReqVO.setAuditTime(LocalDateTime.now());
            if (StringUtils.isNotBlank(updateReqVO.getRejectReason())) {
                updateReqVO.setRejectReason(updateReqVO.getRejectReason());
            }
            infoService.updateInfo(updateReqVO);
            messageUtils.createActivityInfoAuditMessage(ActivityInfoConvert.INSTANCE.convert(activityInfo), 1);
        } else {
            //1.审核不通过，发起活动报名退费操作,-1作为退费中的状态
            infoService.updateByStatus(updateReqVO.getId(), (byte) -1);
            //2.发起活动退款
            ActivityInfoDO infoDO = infoService.getInfo(updateReqVO.getId());
            if (Objects.nonNull(infoDO)) {
                //2.1 查找报名信息
                ActivityEnrollDO enrollDO = enrollService.getSelectOne(infoDO.getId(), infoDO.getHeadUserId(), (byte) 0);
                if (Objects.nonNull(enrollDO)) {
                    log.info("活动报名退费-{}", updateReqVO.getId());
                    //3.报名状态更新为退款申请中
                    enrollService.updatePayStatus(enrollDO.getId(), (byte) 3);
                    //4.发起活动退款
                    infoService.createPayRefund(ActivityEnrollConvert.INSTANCE.convert(enrollDO));
                } else {
                    throw exception(ACTIVITY_ENROLL_PAY_REFUND_NOT_EXISTS);
                }
            } else {
                throw exception(ACTIVITY_ENROLL_PAY_REFUND_NOT_EXISTS);
            }
        }
        return success(true);
    }

    /**
     * 活动成立 establish
     */
    @PostMapping("/establish")
    @Operation(summary = "活动成立")
    @Parameter(name = "id", description = "活动id", required = true, example = "1")
    @OperateLog(type = UPDATE)
    @PreAuthorize("@ss.hasPermission('activity:info:establish')")
    public CommonResult<Boolean> establish(@RequestParam("id") Long id) {
        ActivityInfoDO info = infoService.getInfo(id);
        if (Objects.nonNull(info)) {
            if ("1".equals(info.getActiveSource())) {
                if (info.getStatus() == 8) {
                    ActivityInfoUpdateReqVO update = new ActivityInfoUpdateReqVO();
                    update.setId(id);
                    // 9：平台促成
                    update.setStatus((byte) 9);
                    infoService.updateInfo(update);
                }
            }
        } else {
            throw exception(ENROLL_NO_RELATED_ACTIVITIES_FOUND_NOT_EXISTS);
        }
        return success(true);
    }

    @PostMapping("/create")
    @Operation(summary = "创建相亲活动信息")
    @PreAuthorize("@ss.hasPermission('activity:info:create')")
    public CommonResult<Long> createInfo(@Valid @RequestBody ActivityInfoCreateReqVO createReqVO) {
        genActiveNoCommonUtil.addActiveNo(createReqVO);
        createReqVO.setCostShare((byte) 1);
        List<ActivityPackageCreateReqVO> packageCreateReqVOS = createReqVO.getPackageProductRespVOList();
        if (CollectionUtils.isEmpty(packageCreateReqVOS)) {
            return error(500, "活动商品信息不能为空");
        }
        List<Long> collect = packageCreateReqVOS.stream().map(ActivityPackageCreateReqVO::getProductType).collect(Collectors.toList());
        String s = parseListToStr(collect);
        createReqVO.setProductType(s);
        if (StringUtils.isNotBlank(createReqVO.getActiveCost())) {
            // 先将金额转成分后进行处理
            double number = Double.parseDouble(createReqVO.getActiveCost());
            // 转换为分，乘以100后取整
            int cents = (int) (number * 100);
            // 将分转换为 BigDecimal 类型
            int quotient = cents / 100;
            BigDecimal amountInCents = new BigDecimal(quotient);
            createReqVO.setActiveCost(amountInCents.toString());
        }

        return success(infoService.createCommonInfo(createReqVO));
    }
}
